package com.tloss.stdao.service;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.Query;

import com.tloss.Constants;
import com.tloss.stdao.JPAResourceBean;
import com.tloss.stdao.ResidualStock;

public class ResidualStockService implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -6456481719427322873L;

	public ResidualStock select(String username, String stock, int value) {
		EntityManager em = JPAResourceBean.getEMF().createEntityManager();
		Query q = em
				.createQuery("select t from ResidualStock t where t.username=?1 and t.stock =?2 and t.value=?3");
		q.setParameter(1, username);
		q.setParameter(2, stock);
		q.setParameter(3, value);
		ResidualStock residualStock = (ResidualStock) q.getSingleResult();
		em.close();
		return residualStock;
	}

	public List<ResidualStock> select(String username) {
		EntityManager em = JPAResourceBean.getEMF().createEntityManager();
		Query q = em
				.createQuery("select t from ResidualStock t where t.username=?1 order by t.stock ASC");
		q.setParameter(1, username);
		List<ResidualStock> residualStocks = q.getResultList();
		/*
		 * Fix Object Manager has been closed dataNucleus JPA
		 * http://code.google.com/p/datanucleus-appengine/issues/detail?id=46
		 * Solved with this just after the query execution:
		 * liste.size();
		 */
		residualStocks.size();
		em.close();
		return residualStocks;
	}

	public void update(String username, String stock, int value, int quality,
			String transactionType) {
		EntityManager em = JPAResourceBean.getEMF().createEntityManager();
		if (Constants.BUY.equals(transactionType)) {
			Query q = em
					.createQuery("select t from ResidualStock t where t.username=?1 and t.stock =?2 and t.value=?3");
			q.setParameter(1, username);
			q.setParameter(2, stock);
			q.setParameter(3, value);
			ResidualStock residualStock = null;
			try {
				residualStock = (ResidualStock) q.getSingleResult();
			} catch (NoResultException e) {

			} catch (NonUniqueResultException e) {

			}
			if (residualStock != null) {
				EntityTransaction transaction = em.getTransaction();
				transaction.begin();
				residualStock.setQuality(residualStock.getQuality() + quality);
				transaction.commit();
			} else {
				residualStock = new ResidualStock();
				EntityTransaction transaction = em.getTransaction();
				transaction.begin();
				residualStock.setStock(stock);
				residualStock.setQuality(quality);
				residualStock.setUsername(username);
				residualStock.setValue(value);
				em.persist(residualStock);
				transaction.commit();
			}
		} else if (Constants.SELL.equals(transactionType)) {
			Query q = em
					.createQuery("select t from ResidualStock t where t.username=?1 and t.stock =?2 order by t.value ASC");
			q.setParameter(1, username);
			q.setParameter(2, stock);
			List<ResidualStock> residualStocks = q.getResultList();
			while (quality > 0 && !residualStocks.isEmpty()) {
				ResidualStock residualStock = residualStocks.get(0);
				if (quality >= residualStock.getQuality()) {
					EntityTransaction transaction = em.getTransaction();
					transaction.begin();
					em.remove(residualStock);
					transaction.commit();
				} else {
					EntityTransaction transaction = em.getTransaction();
					transaction.begin();
					residualStock.setQuality(residualStock.getQuality()
							- quality);
					transaction.commit();
				}
				quality = quality - residualStock.getQuality();
			}
		}
		em.close();
	}
}
